import { ipcRenderer } from 'electron'
import { WindowConfig } from 'types/global'

// 定义IPC接口类型
export interface WindowControlAPI {
  minimize: () => void
  maximize: () => void
  close: () => void
  isMaximized: () => Promise<boolean>
  onMaximizeChange: (callback: (maximized: boolean) => void) => void
  removeMaximizeChangeListener: () => void
  checkWindowState: () => Promise<boolean>
  getWindowConfig: () => Promise<WindowConfig>
  applyWindowConfig: (config: WindowConfig) => Promise<boolean>
}

export interface IpcAPI {
  windowControl: WindowControlAPI
  record: RecordAPI
  file: FileAPI
  on: (channel: string, listener: (...args: any[]) => void) => void
  once: (channel: string, listener: (...args: any[]) => void) => void
  removeAllListeners: (channel: string) => void
  removeListener: (channel: string, listener: (...args: any[]) => void) => void
  invoke: (channel: string, ...args: any[]) => Promise<any>
}

export interface RecordAPI {
  startRecording: () => Promise<void>
  stopRecording: () => Promise<void>
  getDisplayMedia: () => Promise<void>
  saveVideo: (videoUrl: string) => Promise<void>
}

export interface FileAPI {
  selectDirectory: () => Promise<{ success: boolean; path?: string; error?: string }>
}

/**
 * IPC渲染进程事件管理类
 * 用于集中处理所有从渲染进程发送到主进程的IPC请求
 */
class IpcRendererHandler implements IpcAPI {
  // 存储最大化状态变化的回调函数
  private maximizeChangeCallback: ((maximized: boolean) => void) | null = null

  /**
   * 窗口控制相关方法
   */
  public windowControl: WindowControlAPI = {
    /**
     * 最小化窗口
     */
    minimize: (): void => {
      ipcRenderer.send('window-control', 'minimize')
    },

    /**
     * 最大化/还原窗口
     */
    maximize: (): void => {
      ipcRenderer.send('window-control', 'maximize')
    },

    /**
     * 关闭窗口
     */
    close: (): void => {
      ipcRenderer.send('window-control', 'close')
    },

    /**
     * 获取窗口最大化状态
     */
    isMaximized: (): Promise<boolean> => {
      return ipcRenderer.invoke('is-maximized')
    },

    /**
     * 监听窗口最大化状态变化
     * @param callback 状态变化回调函数
     */
    onMaximizeChange: (callback: (maximized: boolean) => void): void => {
      // 移除之前的监听器以避免重复
      this.windowControl.removeMaximizeChangeListener()

      // 保存回调函数引用以便后续可以移除
      this.maximizeChangeCallback = callback

      // 添加监听器
      ipcRenderer.on('window-maximized-change', (_event, maximized: boolean) => {
        if (this.maximizeChangeCallback) {
          this.maximizeChangeCallback(maximized)
        }
      })
    },

    /**
     * 移除窗口最大化状态变化监听
     */
    removeMaximizeChangeListener: (): void => {
      if (this.maximizeChangeCallback) {
        ipcRenderer.removeAllListeners('window-maximized-change')
        this.maximizeChangeCallback = null
      }
    },

    /**
     * 检查窗口状态
     */
    checkWindowState: (): Promise<boolean> => {
      return new Promise((resolve) => {
        ipcRenderer.on('window-maximized-change', (_event, maximized: boolean) => {
          resolve(maximized)
        })
      })
    },

    /**
     * 获取窗口当前配置
     */
    getWindowConfig: (): Promise<WindowConfig> => {
      return ipcRenderer.invoke('get-window-config')
    },

    /**
     * 应用窗口配置
     */
    applyWindowConfig: (config: WindowConfig): Promise<boolean> => {
      return ipcRenderer.invoke('apply-window-config', config)
    }
  }

  public record: RecordAPI = {
    startRecording: (): Promise<void> => {
      return ipcRenderer.invoke('start-recording')
    },

    stopRecording: (): Promise<void> => {
      return ipcRenderer.invoke('stop-recording')
    },

    getDisplayMedia: (): Promise<void> => {
      return ipcRenderer.invoke('get-display-media')
    },

    saveVideo: (videoUrl: string): Promise<void> => {
      return ipcRenderer.invoke('record:save-video', videoUrl)
    }
  }

  /**
   * 文件操作相关方法
   */
  public file: FileAPI = {
    /**
     * 选择文件夹
     * @returns 包含成功状态和所选路径的对象
     */
    selectDirectory: async (): Promise<{ success: boolean; path?: string; error?: string }> => {
      return await ipcRenderer.invoke('file:selectDirectory')
    }
  }

  /**
   * 注册监听来自主进程的消息
   * @param channel 频道名称
   * @param listener 回调函数
   */
  public on(channel: string, listener: (...args: any[]) => void): void {
    ipcRenderer.on(channel, (_event, ...args) => listener(...args))
  }

  /**
   * 注册一次性监听来自主进程的消息
   * @param channel 频道名称
   * @param listener 回调函数
   */
  public once(channel: string, listener: (...args: any[]) => void): void {
    ipcRenderer.once(channel, (_event, ...args) => listener(...args))
  }

  /**
   * 移除特定频道的所有监听器
   * @param channel 频道名称
   */
  public removeAllListeners(channel: string): void {
    ipcRenderer.removeAllListeners(channel)
  }

  // 移除指定通道的监听器
  public removeListener(channel: string, listener: (...args: any[]) => void): void {
    // 调用ipcRenderer的removeListener方法，移除指定通道的监听器
    ipcRenderer.removeListener(channel, listener)
  }

  /**
   * 向主进程发送请求并等待回复
   * @param channel 频道名称
   * @param args 参数列表
   * @returns Promise 结果
   */
  public invoke(channel: string, ...args: any[]): Promise<any> {
    return ipcRenderer.invoke(channel, ...args)
  }
}

// 导出单例实例
export const ipc = new IpcRendererHandler()
